package com.example.extenddemo.utils;

import com.alibaba.fastjson.JSON;
import com.example.extenddemo.entity.WebSocketMessage;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName WebSocketServer
 * @Description TODO
 * @Author 郭敖
 * @Date 2024年03月25日 19:11
 * @Version 1.0
 */
@Component
@Slf4j
@ServerEndpoint("/websocket")
public class WebSocketServer {

    /**
     * 某个客户端连接的session
     */
    private Session session;

    private static ConcurrentHashMap<String,Session> clientMap = new ConcurrentHashMap<>();

    /**
     * 建立连接后调用的方法
     * @param session
     */
    @OnOpen
    public void onOpen(Session session){
        log.info("-----websocket成功连接------");
        log.info("websocket的session{}",session);
        List<String> list = session.getRequestParameterMap().get("id");
        log.info("list：{}",list);
        this.session = session;
        clientMap.put(list.get(0),this.session);
    }

    /**
     * 处理客户端失败连接
     */
    @OnClose
    public void onClose(){
//        clientMap.remove(this.session.getId());
//        log.info("客户端失去连接,其sessionID为："+this.session.getId());
        String id = session.getRequestParameterMap().get("id").get(0);
        clientMap.remove(id);
        log.info("在线的用户数量为：{}",clientMap.size());
        log.info("客户端失去连接,其sessionID为："+id);

    }

    /**
     * 连接报错时的处理方式
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("消息发生错误："+session.getId());
        error.printStackTrace();
    }

    /**
     * 如果需要服务器接受客户端的消息就在这里写了
     * @param text
     */
    @OnMessage
    public void onMessage(String text){
        log.info("接受到客户端传来的消息："+text);
    }

    /**
     * 推送消息
     * getAsyncRemote获取异步端点(推荐使用这个)
     * getBasicRemote获取阻塞端点（不推荐，如果第一次发送失败，就会一直阻塞，影响后面的进行）
     * @param message
     */
    public static void sendMessage(WebSocketMessage message){
        // 遍历向所有用户发送消息
        clientMap.entrySet().stream().forEach(item ->{
            item.getValue().getAsyncRemote().sendText(JSON.toJSONString(message));
        });
    }

    /**
     * 将消息发送给特定的用户
     */
    public static void sendToSpecClient(String clientId,WebSocketMessage webSocketMessage){
        log.info("向特定用户发送消息：{}",clientId);
        if(clientMap.get(clientId) != null){
            log.info("向特定用户发送消息：{}",clientId);
            clientMap.get(clientId).getAsyncRemote().sendText(JSON.toJSONString(webSocketMessage));
        }else{
            log.info("向特定用户发送消息 remove ：{}",clientId);
            clientMap.remove(clientId);
            // throw new RuntimeException("特定用户消息发生错误，请稍后重试");
        }
    }

}
